package com.lcf.context;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.util.List;

/**
 * Created by lancf on 2019/5/14.
 */
public class ClassPathXmlApplicationContext {

    private String xmlPath;

    public ClassPathXmlApplicationContext(String xmlPath) {
        this.xmlPath = xmlPath;
    }

    public Object getBean(String beanId) throws Exception {
        // 1. 读取配置文件
        List<Element> elements = readXml();
        if (elements == null) {
            throw new Exception("改配置文件没有元素");
        }

        //2. 使用beanId查找对应的class地址
        String beanClass = findXmlByIDClass(elements, beanId);

        // 3. 使用反射机制初始化，对象
        Class<?> clazz = Class.forName(beanClass);
        return clazz.newInstance();
    }

    //读取xml配置文件
    public List<Element> readXml() throws Exception {
        SAXReader saxReader = new SAXReader();

        if (StringUtils.isBlank(xmlPath)) {
            throw new Exception("xml路径为空");
        }

        Document document = saxReader.read(getClassXmlInputStream(xmlPath));
        //获取根节点信息
        Element rootElement = document.getRootElement();
        //获取子节点
        List<Element> elements = rootElement.elements();
        if (elements == null || elements.isEmpty()) {
            return null;
        }
        return elements;

    }

    // 读取xml配置文件
    public InputStream getClassXmlInputStream(String xmlPath) {
        InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream(xmlPath);
        return resourceAsStream;
    }

    public String findXmlByIDClass(List<Element> elements, String beanId) throws Exception {
        for (Element element : elements) {
            String beanIdValue = element.attributeValue("id");
            if (beanIdValue == null) {
                throw new Exception("使用该beanId为查找到元素");
            }

            if (!beanIdValue.equals(beanId)) {
                continue;
            }

            //获取class地址属性
            String beanClassValue = element.attributeValue("class");
            if (StringUtils.isNotEmpty(beanClassValue)) {
                return beanClassValue;
            }

        }

        return null;
    }
}
